iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
2

寫在前面

typescript是主要由微軟維護的語言
之於javascript有點像是c++之於c
c++是對於c加上了物件導向的功能,而ts對於js則是加上了型別的檢查功能,讓ts更適合於大型專案
這是由於大型專案時常是多人寫某一部份再進行串接,
因此型別錯誤而導致程式bug的情況很容易出現在大型專案上,可以讓你減少很多除錯的時間

但是

typescript是沒辦法直接執行的
跟java一樣,都必須經過轉譯之後才能在node.js上執行
於是雖然ts可以讓你減少很多除錯的時間,但是又會增加你在編譯的時間
因此也有些人以此反駁認為ts反而不是合在大型專案(因為越大型的專案編譯需要越多時間)

安裝typescript指令工具

由於我們昨天已經安裝好node.js了,而npm則已經常駐於node.js中,因此我們可以使用npm來安裝

等等 什麼是npm?

npm是node.js專屬的套件管理器,負責管理node.js相關的套件
比如我們今天需要安裝的typescript指令工具就是node.js支援的套件之一,
這樣你就不需要特地去找下載的位置,或是下載後需要更新要去哪裡更新等等
都改由npm幫你管理
(像是react的專案生成器等等npm都有支援)
當然,你也可以選擇使用yarn當作你的套件管理器

使用以下指令安裝吧

npm install -g typescript

安裝好之後可以使用

tsc -v

確認,如果安裝正確的話應該會告訴你現在的tsc版本

接著我們使用

tsc --init

來初始化我們的專案

之後你應該會看到一個叫做tsconfig.json的檔案
這個檔案是負責用來紀錄我們專案的相關設定
不過我們今天不會用到他,先點開你的js檔吧

接著我們可以開始寫專案了

import { createInterface } from 'readline';

var read = createInterface({
    input: process.stdin,
    output: process.stdout,
});

/////////////////////////////////////////////

console.log('Tell me what you want to do:');
read.question('(1)T to H (2)H to T\n', (answer:string) => {
  switch(answer) {
    case '1':
        read.question('Please enter the number\n', (number:string) => {
            console.log(t2h(number));
            read.close();
        });
        break;
    case '2':
        read.question('Please enter the number\n', (number:string) => {
            console.log(h2t(number));
            read.close();
        });
      break;
    default:
      console.log('Wrong select');
  }
});

/////////////////////////////////////////////

const t2h = (input: string): string => {
    let tennum:number = +input

    for (let i = 0; i < 16; i++) {
        for (let j = 0; j < 16; j++) {
            for (let k = 0; k < 16; k++) {
                if (
                    Math.pow(16, 2) * i +Math.pow(16, 1) * j +Math.pow(16, 0) * k == tennum
                ) {
                    return returnAE(i)+ returnAE(j) + returnAE(k); //看要不要轉型,不然2056會產生16而非808
                }
            }
        }
    }
    return "";
}

const returnAE = (input: number):string => {
    switch (input) {
        case 10:
            return 'A';
        case 11:
            return 'B';
        case 12:
            return 'C';
        case 13:
            return 'D';
        case 14:
            return 'E';
        case 15:
            return 'F';
        default:
            return input.toString();
    }
}

/////////////////////////////////////////////

const h2t=(input: string): number =>{
    let i = 0;
    let output = 0
    while (i < input.length){
        output += AEreturn(input[i])*Math.pow(16, input.length-i-1);
        i++
    }
    return output
}

const AEreturn=(input :string):number =>{
    switch (input){
        case 'A':
            return 10;
        case 'B':
            return 11;
        case 'C':
            return 12;
        case 'D':
            return 13;
        case 'E':
            return 14;
        case 'F':
            return 15;
        default:
            return +input
    }
}

這時候如果你有安裝語法檢查之類的套件的話應該會看到紅線
這是由於模組的關係,我們可以使用

npm i @types/node

來使用node的模組
這樣紅線就消失了,同時你的專案也多了一些設定檔

接著你可以使用

tsc convert.ts

這個指令會幫你把ts檔轉成js檔

然後你就可以使用昨天node來執行js檔,應該會得到與昨天相同的結果

下面我們開始解釋程式碼

import

import { createInterface } from 'readline';

var read = createInterface({
    input: process.stdin,
    output: process.stdout,
});

昨天我們使用 var 來引入的寫法是原生的js寫法
而這種使用import關鍵字的寫法則是ES6新加入的寫法

什麼是ES6?

ES6是由ECMA國際這間公司所發布的標準,有點像是ISO標準一樣
成立標準的用意在於使所有人都可以遵照這個標準來實做
以同樣由ECMA國際頒布的CD-ROM標準來說,以往各家廠商都是按照自己格式來實做自己的CD或是播放器
這導致某幾家的CD只能在某幾家廠商的播放器中播放
於是乎大家決定交由ECMA國際來訂定一個大家都遵守的標準,之後大家都照這個標準來製作及設計CD及CD播放器就不會有大家各自不相容的問題了

ES6就是由這家公司於2015年所頒布的javascript標準,因此也被稱為ES2015
標準頒布後由各家瀏覽器自己各自去實做可以實現這個標準的內層
接著各家網路服務工程師只要使用這套語法,就可以於各種瀏覽器上執行了

當然,在ES6之前,也有ES1,ES2,ES3...
而在他之後也有ES2016,ES2017...
只是ES6是一個分水嶺,在那之前有被放棄的ES4.還有時隔十年才出來的ES5
因為標準之間相隔過久,於是有些語法變得跟不上時代,因此在ES6之後變成每年發布一次標準
而ES6在更新的同時也增加了許多新功能,因此大家只要提到ES6就當作是新的語法,而CommomJS則指在ES6之前的語法

而import就是於ES6新增的語法,他取出了readline裡面的creatInterface
因此我們可以直接宣告creatInterface來用,不必在前面加readline
這個寫法在node.js也是可行的,你可以放到昨天的程式碼裡面試試看

方法

const t2h = (input: string): string => {
    let tennum:number = +input

    for (let i = 0; i < 16; i++) {
        for (let j = 0; j < 16; j++) {
            for (let k = 0; k < 16; k++) {
                if ( Math.pow(16, 2) * i +Math.pow(16, 1) * j +Math.pow(16, 0) * k == tennum ) {
                    return returnAE(i)+ returnAE(j) + returnAE(k); //看要不要轉型,不然2056會產生16而非808
                }
            }
        }
    }
    return "";
}

哇靠,這個方法宣告也太帥了吧

這種方法方式叫做箭頭函式,是ES6新增的語法,因此昨天與前天的函式也能這樣宣告
使用箭頭函式的好處在這裡看不太出來,所以我舉幾個簡單的例子

//如果只需要簡單的回傳可以不用{}跟return
const returnAE = (input)=> input.toString;

//當輸入值只有一個的時候可以不用()
const returnAE = input=> input.toString;

// 如果沒有輸入值則需要把()加回去
const returnAE = ()=> "A";

//如果要加{}且要有回傳值則一定要有return
const returnAE = (input)=> {return input.toString};

可以省略很多符號,而且看起來相當直覺
重點是看起來超帥的

等,const是什麼?

在ES6之前,變數的宣告只有一種方式就是var
但是後來人們發現var在使用上會有重複宣告的問題
你可以先用var宣告一個變數之後再用一次var改變他,這個改變甚至可能變更他的型別
所以你有可能原本用var宣告t2h為一個函式,結果在你沒注意到的地方你又宣告t2h為字串
此時就會產生bug

你可以試試看在昨天的node裡面這個改

var t2h = "123"  //加上這一行

console.log('Tell me what you want to do:');
var r1 = read;
r1.question('(1)T to H (2)H to T\n', function (todo) {
    //以下略

此時如果你選用2 想嘗試使用t2h來轉換數字的話會失敗,node.js將會告訴你t2h不是一個function
這時候如果把var t2h = "123" 這一行拿到方法宣告的後面並且再執行看看就又會成功了
因為var的宣告有先搶先贏的原則
於是乎如果你想要使用var宣告還需要去注意先後順序,因此ES6(沒錯,又是他)增加了兩種宣告方式

let

const

let我們已經使用過了,這裡說明一下他的使用情境,
使用let宣告的變數出了{}後便無法使用,讓他有區域的概念
因此我們在使用迴圈時會使用let來做宣告
記得這段嗎?

for (let i = 0; i < 16; i++) {

因為這個i只有在迴圈內會使用,出了這個迴圈就用不到了,因此使用let來宣告

const則跟原本的var相反,沒辦法被重複宣告
你可以嘗試看看使用相同名字來const一個t2h,編輯器應該會立刻告訴你這裡有問題
因此我們通常使用他於不會改變的變數上,例如方法或是一些常數(比方說const pi = 3.1415926)

讓我們回來繼續看方法的結構,由於ts建議使用強型別,因此在方法的參數與回傳值的部份都建議加上型別的宣告,格式如下

const 方法名稱 = (參數名稱: 參數型別):回傳值型別 => {
const t2h = (input: string):string => {

其餘的部份跟js類似就不特別介紹了

型別轉型

let tennum:number = +input
let tennum:number = parseInt(input) //或是使用js的轉型方法

ts提供了一個簡單的轉型方式,雖然用js方法也是可行的,但是學ts就用ts的轉型方式吧
這裡要注意的是在ts中,數字只有一種型別,叫做number
實際上就相當於C#當中的double,一種具有小數點的浮點數
因此在ts中是沒有int整數型別的喔

也因為+是一種語法糖(給工程師們的糖果)
因此在AEreturn的回傳值你也可以看到

default:
    return +input

使用+來幫助轉型

在大部份的時候合法的js語法都是合法的ts語法,因此有了前兩天的經驗,加上之前介紹C#跟java等強型別語言的經驗,學習起來應該輕鬆很多

來複習今天學了些什麼吧

  • ES6的基本概念(跟ES5之前版本的差異)
  • 箭頭函式
  • 宣告變數的三種方式
  • 型別轉型

通常我會建議就算是後端的工程師也可以學習一下javascript
第一javascript相較其他語言算是簡單(只是有很多陷阱,比方說this)
第二是台灣很常見要求後端的工程師寫一下自己server的後台
所以不管你想不想學最終都還是要會前端的js

我們到目前為止已經學了五種語言了

其中除了python以外,C#,java,javascript,typescript都有一個共同的祖先
C/C++
這種祖先為C/C++的語言我們又稱為類C語言
因此我們明天就來學C/C++吧


上一篇
node.js 被打開的潘多拉盒子
下一篇
C/C++ 如果有朋友建議你程式語言先學C/C++,我建議你立刻跟他絕交
系列文
你會十五種程式語言?不,我會十五種HelloWorld.為了避免這種狀況,因此寫了這篇:淺入淺出十五種程式語言30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
skycover
iT邦新手 4 級 ‧ 2020-09-11 20:50:45

如果有任何寫不清楚或是觀念沒有很明白的話請留言告知我
會盡快補上

如果有任何寫錯的地方也麻煩留言告知我
會盡快修正

感謝各位

我要留言

立即登入留言